package cse.om.data;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

public class DatabaseManager {

	private static final EntityManagerFactory entityManagerFactory;
	private static final EntityManager entityManager;
	private static final ProfileJpaController profileController;
	private static final CommentJpaController commentController;
	private static final CriteriaBuilder criteriaBuilder;

	static {
		entityManagerFactory = Persistence.createEntityManagerFactory("OpinionMiningPU");
		entityManager = entityManagerFactory.createEntityManager();
		criteriaBuilder = entityManager.getCriteriaBuilder();
		profileController = new ProfileJpaController(entityManagerFactory);
		commentController = new CommentJpaController(entityManagerFactory);
	}

	public static Profile getProfileById(Long profileId) {
		return profileController.findProfile(profileId);
	}

	public static List<Profile> getAllProfiles() {
		return profileController.findProfileEntities();
	}

	public static List<Comment> getAllComments() {
		return commentController.findCommentEntities();
	}

	public static Map<Long, Object[]> getCommentCount() {
		Map<Long, Object[]> result = new HashMap<>();

		Query q = entityManager.createNativeQuery("select c.OwnerUserId, COUNT(c.OwnerUserId) as CommentCount, "
			+ "	MAX(c.Time) as UpdateTime "
			+ "from Comment as c "
			+ "group by c.OwnerUserId");
		List<Object[]> list = q.getResultList();
		for (Object[] o : list) {
			result.put((Long) o[0], new Object[]{o[1], o[2]});
		}

		return result;
	}

	public static List<Comment> getCommentByOwnerId(Long profileId, Date timeFrom, Date timeTo) {

		String from = timeFrom != null ? String.valueOf(timeFrom.getTime() / 1000) : "0";
		String to = timeTo != null ? String.valueOf(timeTo.getTime() / 1000 + 86400) : "999999999999";

		CriteriaQuery<Comment> cq = criteriaBuilder.createQuery(Comment.class);
		Root<Comment> cm = cq.from(Comment.class);
		cq.select(cm);
		cq.where(criteriaBuilder.equal(cm.get(Comment_.ownerUserId), profileId),
			criteriaBuilder.greaterThanOrEqualTo(cm.get(Comment_.time), from),
			criteriaBuilder.lessThanOrEqualTo(cm.get(Comment_.time), to));
		return entityManager.createQuery(cq).getResultList();
	}
}
